import { useQuasar } from '@teld/q-components';
import useMappingProps from 't/common/hooks/useMappingProps';
import {
  commonProps,
  createNameSpace,
  pickOwnForBasicComponent,
} from 't/common/utils';
import {
  defineComponent,
  onMounted,
  ref,
  computed,
  reactive,
  watch,
  nextTick,
  onBeforeUnmount,
} from 'vue';
import './index.scss';

import operations from './operations';
import { useDraggable } from '../vueuse/core/useDraggable';

import {
  SCALE_STEP,
  MIN_SCALE,
  ROTATE_STEP,
} from 't/bussiness/image-preview/utils/constants';


/**
 * 图片预览组件
 */
export default defineComponent({
  name: createNameSpace('ImagePreview'),
  props: {
    ...commonProps,
    /** v-mode 用，类型`Boolean | String | null | undefined` */
    modelValue: {
      default: null,
    },
    srcList: {
      type: Array,
      default: () => [],
    },
  },
  emits: ['update:model-value'],

  setup(props, { attrs, emit, expose, slots }) {
    const $q = useQuasar();
    const selfRef = ref();
    const imgDragRef = ref(null);
    const [mappingProps, mappingExpose] = useMappingProps(props);

    console.log(props.srcList, $q.platform);

    const total = computed(() => mappingProps.srcList.length);

    /**
     * @summary 初始化图片索引
     * @returns 当前图片索引
     * @description
     * - 图片列表为空时，返回 -1
     * - 如果未单独指定图片地址，返回 -1
     * - 如果指定的图片不在列表中，返回 -1
     * - 否则，返回指定图片在列表中的索引
     */
    const initIndex = () => {
      if (total.value < 1 || !props.modelValue) return -1;
      return props.srcList.findIndex(v => v === props.modelValue);
    };
    const currentIndex = ref(initIndex());
    const isFitContain = ref(true);
    watch(
      () => props.modelValue,
      v => {
        console.log(`watch src change to ${v}`);
        currentIndex.value = initIndex();
        isFitContain.value = true;
      },
      { immediate: true },
    );
    // const currentSrc = computed(() =>
    //   currentIndex.value > -1 ? props.srcList[currentIndex.value] : props.modelValue,
    // );

    const imgPosition = ref();
    const imgScale = ref(1);
    const imgRotate = ref(0);
    const imgScaleRotate = computed(() => {
      // scale(1.015) rotate(0deg)
      return `scale(${imgScale.value}) rotate(${imgRotate.value}deg)`;
    });
    const resetScaleRotate = () => {
      imgScale.value = 1;
      imgRotate.value = 0;
    };
    /**
     * @summary 左右切换图片箭头指示器的显示控制计算属性
     * @description 显示指示器需要以下必要条件：
     * - 桌面端，且
     * - 当图片列表长度大于1时，且
     * - 当前图片索引大于 -1 时（即指定图片属于预览图片列表）
     */
    const indicatorVisible = computed(() => {
      return (
        total.value > 1 && currentIndex.value > -1
      );
    });
    /**
     * 图片预览器是否可见
     * 用计算属性实现对入参的双向绑定
     */
    const vModelValue = computed({
      get() {
        return typeof props.modelValue === 'string' && props.modelValue;
      },
      set(v) {
        emit('update:model-value', v);
      },
    });

    /** 实现图片在查看器中的拖拽 */
    useDraggable(imgDragRef, {
      initialValue: { x: 'auto', y: 'auto' },
      preventDefault: true,
      onMove: ({ x, y }) => {
        imgPosition.value = `left:${x}px;top:${y}px`;
      },
    });

    /** 重置拖动位置 */
    const resetPosition = () => {
      imgPosition.value = null;
    };
    const resetAll = () => {
      resetPosition();
      resetScaleRotate();
    };

    /** 滚动轮实现扩大缩放 */
    const handleWheel = e => {
      if (!vModelValue.value) return;

      if (e.deltaY > 0) {
        handleZoomOut(e);
      } else {
        handleZoomIn(e);
      }
      e.preventDefault();
    };
    /** 绑定事件监听 */
    const bindEvents = () => {
      setTimeout(() => {
        imgDragRef.value.addEventListener('wheel', handleWheel, { capture: true});
      }, 50);
    };
    /** 解绑 */
    const unbindEvents = () => {
      imgDragRef.value?.removeEventListener('wheel', handleWheel);
    };
    /** 监听组件显隐，进行事件绑定和解绑，及重置处理 */
    watch(
      vModelValue,
      v => {
        if (v) {
          bindEvents();
        } else {
          unbindEvents();
          resetAll();
        }
      },
      { immediate: true },
    );
    /** 前一张 */
    const handlePrevious = e => {
      if (!indicatorVisible.value) return;
      const newIndex = (currentIndex.value + total.value - 1) % total.value;
      vModelValue.value = props.srcList[newIndex];
      resetAll();
      if (e) {
        // e.preventDefault();
        e.stopPropagation();
      }
    };
    /** 后一张 */
    const handleNext = e => {
      if (!indicatorVisible.value) return;
      const newIndex = (currentIndex.value + 1) % total.value;
      vModelValue.value = props.srcList[newIndex];
      resetAll();
      if (e) {
        // e.preventDefault();
        e.stopPropagation();
      }
    };
    /** 关闭 */
    const handleClose = e => {
      if (e) {
        // e.preventDefault();
        e.stopPropagation();
      }
      vModelValue.value = false;
      resetAll();
    };
    /** 放大 */
    const handleZoomIn = e => {
      imgScale.value += SCALE_STEP;
      if (e) {
        // e.preventDefault();
        e.stopPropagation();
      }
    };
    /** 缩小 */
    const handleZoomOut = e => {
      if (imgScale.value <= MIN_SCALE) return;
      imgScale.value -= SCALE_STEP;
      if (e) {
        // e.preventDefault();
        e.stopPropagation();
      }
    };
    /** 向左旋转 */
    const handleRotateLeft = e => {
      imgRotate.value -= ROTATE_STEP;
      if (e) {
        // e.preventDefault();
        e.stopPropagation();
      }
    };
    /** 向右旋转 */
    const handleRotateRight = e => {
      imgRotate.value += ROTATE_STEP;
      if (e) {
        // e.preventDefault();
        e.stopPropagation();
      }
    };
    /** 切换 fit 模式 */
    const handleToggleFit = e => {
      resetAll();
      isFitContain.value = !isFitContain.value;
      if (e) {
        e.preventDefault();
        e.stopPropagation();
      }
    };

    /**
     * -----------------------
     * 键盘操作 start
     */
    const handleKeyDown = e => {
      if (!vModelValue.value) return;

      switch (e.key) {
        case 'Escape':
          handleClose(e);
          break;

        case 'ArrowLeft':
          handlePrevious(e);
          break;

        case 'ArrowRight':
          handleNext(e);
          break;

        case 'ArrowUp':
          handleZoomIn(e);
          break;

        case 'ArrowDown':
          handleZoomOut(e);
          break;

        default:
          break;
      }
    };

    /**
     * 键盘操作 end
     * -----------------------
     */

    /**
     * 手动打开图片预览，并指定一个图片地址
     * @param {String} src 图片地址
     * @returns
     */
    // const open = src => {
    //   if (!src || !src.length || typeof src !== 'string') return;
    //   vModelValue.value = src;
    // };

    // expose({
    //   ...mappingExpose,
    //   open,
    // });

    onMounted(() => {
      document.body.addEventListener('keydown', handleKeyDown, {
        passive: true,
        capture: true,
      });
    });
    onBeforeUnmount(() => {
      document.body.removeEventListener('keydown', handleKeyDown, {
        passive: true,
        capture: true,
      });
    });

    return () => {
      return vModelValue.value ? (
        <div ref={selfRef} class={['t-image-preview', 'platform-pc']}>
          {/* 图片区域 */}
          <div class={['t-image-preview__img flex fit flex-center']}>
            <div
              ref={imgDragRef}
              className='t-image-preview__img-drag'
              style={{
                position: 'fixed',
              }}
              style={imgPosition.value}
            >
              {props.modelValue && (
                <img
                  src={props.modelValue}
                  style={{
                    'overflow-clip-margin': 'content-box',
                    'overflow': 'clip',
                    'transform': imgScaleRotate.value,
                  }}
                  style={
                    isFitContain.value ? 'max-width:100vw;max-height:100vh' : ''
                  }
                />
              )}
            </div>
          </div>

          {/* 指示器 */}
          {indicatorVisible.value && (
            <>
              <div
                class='t-image-preview__indicator t-image-preview__indicator-left icon-container'
                onClickCapture={handlePrevious}
              >
                <t-icon
                  name='keyboard_arrow_left'
                  size='32px'
                  style='margin:4px'
                ></t-icon>
              </div>
              <div
                class='t-image-preview__indicator t-image-preview__indicator-right icon-container'
                onClickCapture={handleNext}
              >
                <t-icon
                  name='keyboard_arrow_right'
                  size='32px'
                  style='margin:4px'
                ></t-icon>
              </div>
            </>
          )}

          {/* 按钮区域 */}
          <operations
            onZoomIn={handleZoomIn}
            onZoomOut={handleZoomOut}
            onRotateLeft={handleRotateLeft}
            onRotateRight={handleRotateRight}
            isFitContain={isFitContain.value}
            onToggleFit={handleToggleFit}
          />
          {/* 关闭按钮 */}
          <div
            class={['t-image-preview__close icon-container']}
            onClick={handleClose}
          >
            <t-icon name='close' size='32px' style='margin:4px'></t-icon>
          </div>
        </div>
      ) : null;
    };
  },
});
